﻿using SkiaSharp;

namespace micro_test
{
    [TestClass]
    public sealed class Test1
    {
        private static List<SKColor> Colors = new List<SKColor>()
        {
            SKColors.Red,SKColors.DarkBlue,SKColors.DarkRed,SKColors.Black,SKColors.Blue
        };

        [TestMethod]
        public void TestMethod1()
        {
            var length = 3;
            var item = GenerateSliderPuzzle(@"C:\Users\zhuyu\Pictures\Screenshots\屏幕截图5.png");
            //CreateCodeImage(width: length * 40, length: length);

            string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "image.jpg");

            string filePath1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "image1.jpg");
            // 将 SKData 对象保存到本地文件
            using FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
            using MemoryStream memoryStream = new MemoryStream(item.background);
            memoryStream.CopyTo(fs);

            using FileStream fs1 = new FileStream(filePath1, FileMode.OpenOrCreate, FileAccess.Write);
            using MemoryStream memoryStream1 = new MemoryStream(item.slider);
            memoryStream1.CopyTo(fs1);
            Assert.IsTrue(true);
        }
        /// <summary>
        /// 创建题目以及答案
        /// </summary>
        /// <param name="min">最小值</param>
        /// <param name="max">最大值</param>
        /// <param name="len">字符长度</param>
        /// <returns>验证码字符</returns>
        private static string CreateMixVerifyCode(int min, int max, int len)
        {
            // 计算符号
            char[] computeSymbols = { '+', '-', '*', '÷' };
            Random random = new Random();
            List<string> strings = new List<string>();

            // 随机生成多位数字和计算符号
            for (int i = 0; i < len; i++)
            {
                var num = random.Next(min, max + 1);
                strings.Add(num.ToString()); // 数字
                if (i != len - 1)
                {
                    var computeSymbol = random.Next(0, computeSymbols.Length);
                    strings.Add(computeSymbols[computeSymbol].ToString()); // 计算符号
                }
            }

            // 组合成计算公式
            var calculationFormula = string.Join(" ", strings);

            // 调用 Calculate 方法计算结果
            var calculationResult = Calculate(calculationFormula);

            // 确保结果为正整数
            if (calculationResult <= 0)
            {
                return CreateMixVerifyCode(min, max, len); // 重新生成公式
            }

            // 返回计算公式和结果
            return $"{calculationFormula} = ";
        }

        /// <summary>
        /// 计算结果
        /// </summary>
        /// <param name="formula">计算公式</param>
        /// <returns>结果</returns>
        private static int Calculate(string formula)
        {
            // 拆分公式
            var tokens = formula.Split(' ');

            // 先处理乘除
            for (int i = 1; i < tokens.Length - 1; i += 2)
            {
                if (tokens[i] == "*" || tokens[i] == "÷")
                {
                    var leftNum = int.Parse(tokens[i - 1]);
                    var rightNum = int.Parse(tokens[i + 1]);

                    // 处理除法，确保结果为整数
                    if (tokens[i] == "÷" && rightNum != 0)
                    {
                        while (leftNum % rightNum != 0) // 确保整除
                        {
                            rightNum = new Random().Next(1, rightNum); // 随机生成一个新的右操作数
                        }
                    }

                    var result = Compute(leftNum, tokens[i], rightNum);

                    // 更新 tokens 数组
                    tokens[i - 1] = result.ToString();
                    for (int j = i; j < tokens.Length - 2; j++)
                    {
                        tokens[j] = tokens[j + 2];
                    }
                    Array.Resize(ref tokens, tokens.Length - 2);
                    i -= 2; // 调整索引以重新检查新位置
                }
            }

            // 然后处理加减
            int calculationResult = int.Parse(tokens[0]);
            for (int i = 1; i < tokens.Length; i += 2)
            {
                var computeSymbol = tokens[i];
                var rightNum = int.Parse(tokens[i + 1]);
                calculationResult = Compute(calculationResult, computeSymbol, rightNum);
            }

            return calculationResult;
        }

        private static int Compute(int leftNum, string computeSymbol, int rightNum)
        {
            switch (computeSymbol)
            {
                case "+":
                    return leftNum + rightNum;
                case "-":
                    return leftNum - rightNum;
                case "*":
                    return leftNum * rightNum;
                case "÷":
                    return rightNum != 0 ? leftNum / rightNum : 0;
                default:
                    throw new NotImplementedException();
            }
        }

        public void CreateCodeImage(int width = 100, int height = 40, int lineNum = 4, int lineStrookeWidth = 2, int length = 3)
        {
            var verifyCode = string.Empty;
            verifyCode = CreateMixVerifyCode(1, 100, length);
            //创建bitmap位图
            using SKBitmap image2d = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
            //创建画笔
            using SKCanvas canvas = new SKCanvas(image2d);
            //填充白色背景颜色
            canvas.DrawColor(SKColors.White);
            var array = verifyCode.ToArray();
            Random random = new Random();
            for (int i = 0; i < array.Length; i++)
            {
                //将文字写到画布上
                using SKPaint drawStyle = CreatePaint(random.Next(Colors.Count), 20);
                using SKFont font = CreateFont(20);
                canvas.DrawText(array[i].ToString(), i * 8 + 1, height - 10, font, drawStyle);
            }
            //画随机干扰线
            using (SKPaint drawStyle = new SKPaint())
            {
                for (int i = 0; i < lineNum; i++)
                {
                    drawStyle.Color = Colors[random.Next(Colors.Count)];
                    drawStyle.StrokeWidth = lineStrookeWidth;
                    canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle);
                }
            }
            //返回图片byte
            using SKImage img = SKImage.FromBitmap(image2d);
            using SKData p = img.Encode(SKEncodedImageFormat.Jpeg, 100);
            string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "image.jpg");
            // 将 SKData 对象保存到本地文件
            using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                p.SaveTo(fs);
            }
        }
        // 创建画笔
        private SKPaint CreatePaint(int colorNo, float fontSize)
        {
            SKFontStyle sKFontStyle = new SKFontStyle(SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic);
            SKFont font = new SKFont(SKTypeface.FromFamilyName("微软雅黑", sKFontStyle), fontSize);
            SKPaint paint = new SKPaint();
            paint.IsAntialias = true;
            paint.Color = Colors[colorNo];
            return paint;
        }

        private SKFont CreateFont(float fontSize)
        {
            SKFontStyle sKFontStyle = new SKFontStyle(SKFontStyleWeight.Normal, SKFontStyleWidth.Normal, SKFontStyleSlant.Italic);
            SKFont font = new SKFont(SKTypeface.FromFamilyName("微软雅黑", sKFontStyle), fontSize);
            return font;
        }








        public (byte[] background, byte[] slider, SKPoint position) GenerateSliderPuzzle(string backgroundImagePath)
        {
            // 加载自定义背景图
            using var backgroundBitmap = SKBitmap.Decode(backgroundImagePath);
            int width = backgroundBitmap.Width;
            int height = backgroundBitmap.Height;

            // 定义滑块拼图块的形状（自定义路径）
            var path = new SKPath();
            path.MoveTo(20, 20); // 调整路径的尺寸
            path.LineTo(80, 20);
            path.LineTo(80, 40);
            path.LineTo(60, 60);
            path.LineTo(80, 80);
            path.LineTo(20, 80);
            path.Close();

            // 生成滑块拼图块的位置（随机生成）
            var random = new Random();
            var position = new SKPoint(random.Next(0, width - 100), random.Next(0, height - 100)); // 调整位置范围

            // 在背景图上绘制透明缺口
            using var backgroundCanvas = new SKCanvas(backgroundBitmap);
            using var gapPaint = new SKPaint
            {
                Color = SKColors.Transparent,
                BlendMode = SKBlendMode.SrcOut // 使用混合模式实现透明缺口
            };

            // 将路径平移到背景图上的缺口位置
            var offsetPath = new SKPath(path);
            offsetPath.Offset(position.X, position.Y);
            backgroundCanvas.DrawPath(offsetPath, gapPaint);

            // 将背景图保存为字节数组
            using var backgroundImage = SKImage.FromBitmap(backgroundBitmap);
            using var backgroundData = backgroundImage.Encode(SKEncodedImageFormat.Png, 100);
            var updatedBackground = backgroundData.ToArray();

            // 生成滑块拼图块
            var sliderInfo = new SKImageInfo(100, 100); // 调整滑块大小为 100x100
            using var sliderSurface = SKSurface.Create(sliderInfo);
            var sliderCanvas = sliderSurface.Canvas;

            // 设置滑块背景透明
            sliderCanvas.Clear(SKColors.Transparent);

            // 从背景图中提取缺口部分的图像
            using var sliderBitmap = new SKBitmap(100, 100);
            using var sliderCanvasBitmap = new SKCanvas(sliderBitmap);
            sliderCanvasBitmap.DrawBitmap(backgroundBitmap, new SKRect(position.X, position.Y, position.X + 100, position.Y + 100), new SKRect(0, 0, 100, 100));

            // 将提取的图像绘制到滑块拼图块上
            sliderCanvas.DrawBitmap(sliderBitmap, 0, 0);

            // 将滑块拼图块保存为字节数组
            using var sliderImage = sliderSurface.Snapshot();
            using var sliderData = sliderImage.Encode(SKEncodedImageFormat.Png, 100);
            var slider = sliderData.ToArray();

            return (updatedBackground, slider, position);
        }


        //public (byte[] background, byte[] slider, SKPoint position) GenerateSliderPuzzle(string backgroundImagePath)
        //{
        //    // 加载自定义背景图
        //    using var backgroundBitmap = SKBitmap.Decode(backgroundImagePath);
        //    int width = backgroundBitmap.Width;
        //    int height = backgroundBitmap.Height;

        //    // 生成滑块拼图块
        //    var sliderInfo = new SKImageInfo(50, 50); // 滑块大小为 50x50
        //    using var sliderSurface = SKSurface.Create(sliderInfo);
        //    var sliderCanvas = sliderSurface.Canvas;

        //    // 设置滑块背景透明
        //    sliderCanvas.Clear(SKColors.Transparent);

        //    // 绘制滑块拼图块（自定义不规则形状）
        //    using var sliderPaint = new SKPaint
        //    {
        //        Color = SKColors.Blue,
        //        IsAntialias = true,
        //        Style = SKPaintStyle.Fill
        //    };

        //    // 自定义路径（不规则形状）
        //    var path = new SKPath();
        //    path.MoveTo(10, 10);
        //    path.LineTo(40, 10);
        //    path.LineTo(40, 20);
        //    path.LineTo(30, 30);
        //    path.LineTo(40, 40);
        //    path.LineTo(10, 40);
        //    path.Close();

        //    sliderCanvas.DrawPath(path, sliderPaint);

        //    // 生成滑块拼图块的位置（随机生成）
        //    var random = new Random();
        //    var position = new SKPoint(random.Next(0, width - 50), random.Next(0, height - 50));

        //    // 在背景图上绘制缺口
        //    using var backgroundCanvas = new SKCanvas(backgroundBitmap);
        //    using var gapPaint = new SKPaint
        //    {
        //        Color = SKColors.Transparent,
        //        BlendMode = SKBlendMode.SrcOut // 使用混合模式实现透明缺口
        //    };

        //    // 将路径平移到背景图上的缺口位置
        //    var offsetPath = new SKPath(path);
        //    offsetPath.Offset(position.X, position.Y);
        //    backgroundCanvas.DrawPath(offsetPath, gapPaint);

        //    // 将背景图保存为字节数组
        //    using var backgroundImage = SKImage.FromBitmap(backgroundBitmap);
        //    using var backgroundData = backgroundImage.Encode(SKEncodedImageFormat.Png, 100);
        //    var updatedBackground = backgroundData.ToArray();

        //    // 将滑块拼图块保存为字节数组
        //    using var sliderImage = sliderSurface.Snapshot();
        //    using var sliderData = sliderImage.Encode(SKEncodedImageFormat.Png, 100);
        //    var slider = sliderData.ToArray();

        //    return (updatedBackground, slider, position);
        //}

    }
}


